﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Ionic.Zip;
using MS.Utility.Config;
using MS.Utility.Files;

namespace MS.Utility.Files
{
    public class FileUtility
    {
        #region 文件操作
        /// <summary>
        /// 压缩文件
        /// </summary>
        /// <param name="ms"></param>
        /// <param name="zipedFile"></param>
        /// <param name="mode"></param>
        public static void Compress(string fileToZip, string zipedFile, FileAccessMode mode)
        {
            if (!ValidFilePath(fileToZip, mode))
            {
                throw new System.IO.FileNotFoundException("指定要压缩的文件: " + fileToZip + " 不存在!");
            }

            FileStream fileToZipFileStream = AccessReadFile(fileToZip, mode);

            FileStream fs = null;
            if (mode == FileAccessMode.FileByUNC)
            {
                var uri = new Uri(zipedFile);
                string path = Path.GetFullPath(uri.LocalPath);
                var fileInfo = new FileInfo(path);
            }
            else if (mode == FileAccessMode.FileByLocal)
            {
                fs = File.Create(zipedFile);
            }
            using (ZipOutputStream zs = new ZipOutputStream(fs))
            {
                string fileName = Path.GetFileName(zipedFile);
                zs.PutNextEntry(fileName);
                zs.CompressionLevel = Ionic.Zlib.CompressionLevel.BestSpeed;
                int size = 2048;
                byte[] data = new byte[2048];
                while (true)
                {
                    size = fileToZipFileStream.Read(data, 0, data.Length);
                    if (size > 0)
                    {
                        zs.Write(data, 0, size);
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }

        /// <summary>
        /// 解压缩一个 zip 文件。
        /// </summary>
        /// <param name="zipedFile">The ziped file.</param>
        /// <param name="strDirectory">The STR directory.</param>
        /// <param name="password">zip 文件的密码。</param>
        /// <param name="overWrite">是否覆盖已存在的文件。</param>
        public void UnZip(string zipedFile, string strDirectory, string password, bool overWrite, FileAccessMode mode)
        {

            if (strDirectory == "")
                strDirectory = Directory.GetCurrentDirectory();
            if (!strDirectory.EndsWith("\\"))
                strDirectory = strDirectory + "\\";

            using (ZipInputStream s = new ZipInputStream(AccessReadFile(zipedFile, mode)))
            {
                s.Password = password;
                ZipEntry theEntry;

                while ((theEntry = s.GetNextEntry()) != null)
                {
                    string directoryName = "";
                    string pathToZip = "";
                    pathToZip = theEntry.FileName;

                    if (pathToZip != "")
                        directoryName = Path.GetDirectoryName(pathToZip) + "\\";

                    string fileName = Path.GetFileName(pathToZip);

                    Directory.CreateDirectory(strDirectory + directoryName);

                    if (fileName != "")
                    {
                        if ((File.Exists(strDirectory + directoryName + fileName) && overWrite) || (!File.Exists(strDirectory + directoryName + fileName)))
                        {
                            using (FileStream streamWriter = File.Create(strDirectory + directoryName + fileName))
                            {
                                int size = 2048;
                                byte[] data = new byte[2048];
                                while (true)
                                {
                                    size = s.Read(data, 0, data.Length);

                                    if (size > 0)
                                        streamWriter.Write(data, 0, size);
                                    else
                                        break;
                                }
                                streamWriter.Close();
                            }
                        }
                    }
                }

                s.Close();
            }
        }

        /// <summary>
        ///  创建文件，写入流
        /// </summary>
        /// <param name="fileName">文件的绝对路径</param>
        /// <param name="_FileStream">需要写入的流</param>
        public static void WriteFile(string fileName, Stream _FileStream)
        {
            FileStream streamWriter = null;
            try
            {
                if (!File.Exists(fileName))
                {
                    //  创建文件夹
                    DirectoryUtility.CreateDirectoryFromFileName(fileName);
                    // 创建文件
                    streamWriter = File.Create(fileName);
                }
                else
                {
                    streamWriter = File.OpenWrite(fileName);
                }
                int size = 2048;
                byte[] data = new byte[2048];
                while (true)
                {
                    size = _FileStream.Read(data, 0, data.Length);
                    if (size > 0)
                    {
                        streamWriter.Write(data, 0, size);
                    }
                    else
                    {
                        break;
                    }
                }
                _FileStream.Flush();
            }
            finally
            {
                _FileStream.Close();

                if (streamWriter != null)
                {
                    streamWriter.Close();
                }
            }
        }

        /// <summary>
        /// 校验文件是否存在
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <returns>有效</returns>
        public static bool ValidFilePath(string filePath, FileAccessMode mode)
        {
            var retVal = true;

            if (mode == FileAccessMode.FileByUNC)
            {
                var uri = new Uri(filePath);
                string filename = Path.GetFullPath(uri.LocalPath);
                var fileInfo = new FileInfo(filename);
                if (!fileInfo.Exists)
                    retVal = false;

            }
            else if (mode == FileAccessMode.FileByLocal)
            {
                if (!File.Exists(filePath))
                    retVal = false;
            }

            return retVal;
        }

        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="mode">访问模式</param>
        public static void Delete(string filePath, FileAccessMode mode)
        {
            if (mode == FileAccessMode.FileByUNC)
            {
                Uri uri = new Uri(filePath);
                string filename = Path.GetFullPath(uri.LocalPath);
                FileInfo fileInfo = new FileInfo(filename);
                fileInfo.Delete();
            }
            else if (mode == FileAccessMode.FileByLocal)
            {
                File.Delete(filePath);
            }
        }

        /// <summary>
        /// 校验文件目录是否存在
        /// </summary>
        /// <param name="fileDir">文件目录</param>
        /// <returns>文件目录是否存在</returns>
        public static bool ValidFileDirectory(string fileDir, FileAccessMode mode)
        {
            var retVal = true;

            if (mode == FileAccessMode.FileByUNC)
            {
                var dirInfo = new DirectoryInfo(fileDir);
                if (!dirInfo.Exists)
                    retVal = false;
            }
            else if (mode == FileAccessMode.FileByLocal)
            {
                if (!Directory.Exists(fileDir))
                    retVal = false;
            }
            return retVal;
        }

        /// <summary>
        /// 创建目录(如果存在则不创建)
        /// </summary>
        /// <param name="fileDir"></param>
        /// <param name="mode"></param>
        public static void CreateFileDirectory(string fileDir, FileAccessMode mode)
        {

            if (mode == FileAccessMode.FileByUNC)
            {
                var dirInfo = new DirectoryInfo(fileDir);
                if (!dirInfo.Exists)
                    dirInfo.Create();
            }
            else if (mode == FileAccessMode.FileByLocal)
            {
                if (!Directory.Exists(fileDir))
                    Directory.CreateDirectory(fileDir);
            }

        }

        /// <summary>
        /// 获取文件扩展名
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="mode">访问模式</param>
        /// <returns>扩展名</returns>
        public static string GetFileExtension(string filePath, FileAccessMode mode)
        {
            string extension = string.Empty;

            if (mode == FileAccessMode.FileByLocal)
            {
                extension = Path.GetExtension(filePath);
            }
            else if (mode == FileAccessMode.FileByUNC)
            {
                var uri = new Uri(filePath);

                string filename = Path.GetFullPath(uri.LocalPath);

                var fileInfo = new FileInfo(filename);

                extension = fileInfo.Extension;
            }
            return extension;
        }

        /// <summary>
        /// 读取文件
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="mode">访问模式</param>
        /// <returns>文件流</returns>
        public static FileStream AccessReadFile(string filePath, FileAccessMode mode)
        {
            FileStream fs = null;

            if (mode == FileAccessMode.FileByLocal)
            {
                fs = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            }
            else if (mode == FileAccessMode.FileByUNC)
            {
                var uri = new Uri(filePath);

                string filename = Path.GetFullPath(uri.LocalPath);

                var fileInfo = new FileInfo(filename);

                fs = fileInfo.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
            }
            return fs;
        }

        /// <summary>
        /// 读取文件
        /// </summary>
        /// <param name="fileName">文件路径</param>
        /// <returns>返回字节</returns>
        public static byte[] ReadFile(string fileName)
        {

            FileStream pFileStream = null;

            byte[] pReadByte = new byte[0];

            try
            {

                pFileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);

                BinaryReader r = new BinaryReader(pFileStream);

                r.BaseStream.Seek(0, SeekOrigin.Begin);    //将文件指针设置到文件开

                pReadByte = r.ReadBytes((int)r.BaseStream.Length);

                return pReadByte;
            }

            catch
            {
                return pReadByte;
            }

            finally
            {

                if (pFileStream != null)

                    pFileStream.Close();

            }

        }

        /// <summary>  
        /// 将所有HTML标签替换成""  
        /// </summary>  
        public static string StripHTML(string strHtml)
        {
            string HTMLEncode = strHtml;
            if (!String.IsNullOrEmpty(strHtml))
            {
                strHtml = strHtml.Replace(">", "&gt;");
                strHtml = strHtml.Replace("<", "&lt;");
                strHtml = strHtml.Replace("\"", "&quot;");
                strHtml = strHtml.Replace("\'", "&#39;");
                strHtml = strHtml.Replace("\n", "<br/>");
                strHtml = strHtml.Replace("\r", "<br/>");
                HTMLEncode = strHtml;
            }
            return HTMLEncode;
        }

        public static void Copy(string copyFile, string newFile, FileAccessMode mode)
        {
            if (mode == FileAccessMode.FileByUNC)
            {
                var uri = new Uri(copyFile);
                var newUri = new Uri(newFile);

                FileInfo file = new FileInfo(Path.GetFullPath(uri.LocalPath));


                file.CopyTo(Path.GetFullPath(newUri.LocalPath), true);
            }
            else if (mode == FileAccessMode.FileByLocal)
            {
                FileInfo file = new FileInfo(copyFile);
                file.CopyTo(newFile, true);
            }
        }
        #endregion
        /// <summary>
        /// 获取一个随机的文件名
        /// </summary>
        /// <returns></returns>
        public static string GetFileName()
        {
            return Guid.NewGuid().ToString("N");
        }
    }
}

